package cn.iocoder.boot.service.impl.supplier;

import cn.hutool.crypto.digest.DigestUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import cn.iocoder.boot.dto.OrderTo;
import cn.iocoder.boot.dto.SKU;
import cn.iocoder.boot.entity.ComponentPrice;
import cn.iocoder.boot.entity.ComponentStock;
import cn.iocoder.boot.enums.SupplierCodeEnum;
import cn.iocoder.boot.service.CallLimitService;
import cn.iocoder.boot.service.ComponentPriceService;
import cn.iocoder.boot.service.ComponentStockService;
import cn.iocoder.boot.service.HttpRequestLogService;
import cn.iocoder.boot.service.impl.SalePriceConfigServiceImpl;
import cn.iocoder.boot.utils.MessageUtil;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.time.Instant;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

import static cn.iocoder.boot.enums.SupplierCodeEnum.IC;
import static cn.iocoder.boot.enums.SupplierCodeEnum.SHT;

@Service
@DS("master")
@Slf4j
public class YunhanServiceImpl {


    @Resource
    private CallLimitService callLimitService;

    @Resource
    private ComponentStockService componentStockService;

    @Resource
    private ComponentPriceService componentPriceService;

    @Resource
    private SalePriceConfigServiceImpl salePriceConfigService;
    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Value("${icquote.appId}")
    private String appId;
    @Value("${icquote.appKey}")
    private String appKey;
    @Value("${icquote.requestUrl}")
    private String requestUrl;

    @Resource
    private HttpRequestLogService httpRequestLogService;


    public String updateToken() {
        // 获取当前时间戳
        long timestamp = Instant.now().getEpochSecond();

        // 准备参数
        Map<String, String> params = new HashMap<>();
        params.put("_t", String.valueOf(timestamp));
        params.put("appid", appId);
        String queryString = params.entrySet().stream()
                .sorted(Map.Entry.comparingByKey())
                .map(entry -> entry.getKey() + "=" + entry.getValue())
                .collect(Collectors.joining("&"));
        String stringToSign = queryString + "|" + appKey;

        // 计算MD5签名
        String sign = DigestUtil.md5Hex(stringToSign);

        // 创建JSON对象
        Map<String, Object> jsonMap = new HashMap<>();
        jsonMap.put("_t", timestamp);
        jsonMap.put("appid", appId);
        jsonMap.put("sign", sign);
        String json = JSONUtil.toJsonStr(jsonMap);

        // 发送HTTP POST请求并处理响应
        String response = sendPostRequest(requestUrl + "/v2/new-token/create", json);
        String token = extractTokenFromResponse(response);
        log.info("提取到的token: " + token);

        Long expireTime = extractTimeFromResponse(response);

        if (StringUtils.isNotBlank(token) && expireTime != null) {
            stringRedisTemplate.opsForValue().set("supplier:yunhantoken", token, expireTime - 300, TimeUnit.SECONDS);
        }
        return token;
    }


    /**
     * 使用Hutool的HttpUtil发送POST请求
     */
    private String sendPostRequest(String url, String jsonBody) {
        int maxRetries = 2; // 最大重试次数
        int retryCount = 0; // 当前重试次数

        while (retryCount <= maxRetries) {
            try (HttpResponse response = HttpRequest.post(url)
                    .body(jsonBody)
                    .header("Content-Type", "application/json; utf-8")
                    .header("Accept", "application/json")
                    .timeout(10000)  // 单位为毫秒，10000毫秒 = 10秒
                    .execute()) {

                httpRequestLogService.saveHttpRequestLog(url, "YunHan_queryOne", jsonBody, response.body(), response.getStatus());
                return response.body();

            } catch (Exception e) {
                log.error("发送POST请求失败（第{}次尝试）: {}", retryCount + 1, url, e);

                // 判断是否需要重试（连接超时且未达到最大重试次数）
                if (e.getMessage() != null && (e.getMessage().contains("Connect timed out") || e.getMessage().contains("Connection timed out") || e.getMessage().contains("Read timed out"))
                        && retryCount < maxRetries) {
                    retryCount++;
                    log.info("POST请求将进行第{}次重试...", retryCount);
                    continue; // 继续重试循环
                }

                // 不需要重试或达到最大重试次数，发送消息
                MessageUtil.sentMessage("26827", "云汉sendPostRequest【" + url + "】" + e.getMessage(), "云汉sendPostRequest");
                return "";
            }
        }

        // 达到最大重试次数后返回空字符串
        return "";
    }

    /**
     * 发送表单数据请求
     */
    private String sendFormRequest(String url, Map<String, String> formData) {

        Map<String, Object> objectMap = new HashMap<>(formData);
        try (HttpResponse response = HttpRequest.post(url)
                .form(objectMap)
                .header("Accept", "application/json")
                .execute()) {

            return response.body();
        } catch (Exception e) {
            log.error("发送表单请求失败: " + url, e);
            return "";
        }
    }

    private String extractTokenFromResponse(String response) {
        if (StringUtils.isBlank(response)) {
            return null;
        }
        JSONObject jsonObject = JSONUtil.parseObj(response);
        JSONObject result = jsonObject.getJSONObject("result");
        return result != null ? result.getStr("token") : null;
    }

    private Long extractTimeFromResponse(String response) {
        if (StringUtils.isBlank(response)) {
            return null;
        }
        JSONObject jsonObject = JSONUtil.parseObj(response);
        JSONObject result = jsonObject.getJSONObject("result");
        return result != null ? result.getLong("expireTime") : null;
    }


    public String getToken() {
        String token = stringRedisTemplate.opsForValue().get("supplier:yunhantoken");

        if (StringUtils.isNotBlank(token)) {
            return token;
        } else {
            return updateToken();
        }
    }

    public List<ComponentPrice> queryOne(String model, String currency, Map<String, BigDecimal> componentSupplierMap) {
        String token = getToken();
        long timestamp = Instant.now().getEpochSecond();

        Map<String, Object> jsonMap = new HashMap<>();
        jsonMap.put("_t", timestamp);
        jsonMap.put("token", token);
        jsonMap.put("keyword", model);
        String json = JSONUtil.toJsonStr(jsonMap);

        callLimitService.supplierLimitCall(SHT.getCode());
        String response = sendPostRequest(requestUrl + "/search-v1/products/get-single-goods-new", json);

        log.info("{} 云汉 queryOne API response: {}", model, response);

        com.alibaba.fastjson.JSONObject jsonResponse = JSON.parseObject(response);
        int code = jsonResponse.getIntValue("code");

        if (code == 0) {
            JSONArray dataArray = jsonResponse.getJSONArray("result");
            List<ComponentPrice> componentPriceList = new ArrayList<>();
            if (dataArray != null) {
                for (int i = 0; i < dataArray.size(); i++) {
                    com.alibaba.fastjson.JSONObject item = dataArray.getJSONObject(i);
                    ComponentStock stock = new ComponentStock();
                    stock.setPicUrl("https:" + item.getString("img_url"));
                    stock.setModel(item.getString("pro_name"));
                    stock.setType(item.getString("cate_name"));
                    stock.setKeyword(model);
                    stock.setMinNum(StringUtils.isEmpty(item.getString("moq")) ? null :
                            Integer.valueOf(item.getString("moq")));
                    stock.setPartnumber(item.getString("sku"));
                    stock.setBrand(item.getString("pro_maf"));
                    stock.setSpecifications(item.getString("pro_desc"));
                    stock.setStockType(1);
                    stock.setSupplierCode(IC.getCode());
                    stock.setUniqueId(SupplierCodeEnum.IC.getCode() + "_" + item.getString("sku"));

                    // 处理价格和数量信息
                    JSONArray priceArray = item.getJSONArray("rmb");
                    if (Objects.equals(currency, "USD")) {
                        priceArray = item.getJSONArray("usd");
                    }
                    JSONArray numsArray = item.getJSONArray("nums");

                    JSONArray resultArray = new JSONArray();
                    for (int k = 0; k < priceArray.size(); k++) {
                        JSONObject priceInfo = new JSONObject();
                        priceInfo.put("Price", priceArray.get(k).toString());
                        priceInfo.put("Currency", currency);
                        priceInfo.put("Quantity", numsArray.get(k).toString());
                        resultArray.add(priceInfo);
                    }

                    // 保存库存信息
                    componentStockService.saveComponentStockOfUniqueKey(stock);
                    String saleJson = salePriceConfigService.getSaleJson(
                            resultArray.toJSONString(),
                            stock.getPartnumber(),
                            currency
                    );

                    ComponentPrice componentPrice = new ComponentPrice(
                            stock.getUniqueId(),
                            resultArray.toJSONString(),
                            item.getLong("stock"),
                            null,
                            item.getString("package"),
                            currency,
                            stock.getPartnumber(),
                            resultArray.toJSONString(),
                            saleJson,
                            componentSupplierMap.getOrDefault(SHT.getCode(), BigDecimal.valueOf(2))
                    );

                    componentPriceService.createComponentPriceOfUniqueKey(componentPrice);
                    componentPrice.setStockInfo(stock);
                    componentPriceList.add(componentPrice);
                }
            }
            return componentPriceList;
        }
        return new ArrayList<>();
    }

    public void query(List<String> models, String currency, Map<String, BigDecimal> componentSupplierMap) {
        for (String model : models) {
            queryOne(model, currency, componentSupplierMap);
        }
    }

    // 云汉下单接口
    public CommonResult order(OrderTo to) {
        String token = getToken();
        long timestamp = Instant.now().getEpochSecond();

        // 准备表单数据
        Map<String, String> formData = new HashMap<>();
        formData.put("_t", String.valueOf(timestamp));
        formData.put("token", token);

        if (StringUtils.isNotBlank(to.getUserMark())) {
            formData.put("user_mark", to.getUserMark());
        }

        List<SKU> skuList = to.getSkuList();
        // 添加商品到表单数据
        for (int i = 0; i < skuList.size(); i++) {
            SKU sku = skuList.get(i);
            formData.put("items[" + i + "][pro_num]", sku.getNum().toString());
            formData.put("items[" + i + "][sku]", sku.getSku());
        }

        // 发送添加到购物车请求
        String response = sendFormRequest(requestUrl + "/api-v1/cart/batch-add", formData);
        log.info("云汉购物车返回: {}", response);

        JSONObject jsonResponse = JSONUtil.parseObj(response);
        JSONObject result = jsonResponse.getJSONObject("result");

        // 处理失败结果
        cn.hutool.json.JSONArray failResult = result.getJSONArray("fail_result");
        if (failResult != null && !failResult.isEmpty()) {
            StringBuilder errorMsg = new StringBuilder();
            for (int i = 0; i < failResult.size(); i++) {
                JSONObject failItem = failResult.getJSONObject(i);
                String sku = failItem.getStr("sku");
                String message = failItem.getStr("error_message");

                if (i > 0) {
                    errorMsg.append(", ");
                }
                errorMsg.append("失败型号：").append(sku).append("，").append(message);
            }
            return CommonResult.error(500, errorMsg.toString());
        }

        // 处理成功结果，创建订单
        ObjectMapper objectMapper = new ObjectMapper();
        List<Integer> cartIdList = new ArrayList<>();

        try {
            JsonNode rootNode = objectMapper.readTree(response);
            JsonNode successResultNode = rootNode.path("result").path("success_result");

            for (JsonNode node : successResultNode) {
                int cartId = node.path("cart_id").asInt();
                cartIdList.add(cartId);
            }

            log.info("购物车ID列表: {}", cartIdList);

            if (!cartIdList.isEmpty()) {
                Map<String, String> orderFormData = new HashMap<>();
                orderFormData.put("_t", String.valueOf(timestamp));
                orderFormData.put("token", token);
                orderFormData.put("user_mark", to.getUserMark());

                if (StringUtils.isNotBlank(to.getRemarks())) {
                    orderFormData.put("remarks", to.getRemarks());
                }
                if (StringUtils.isNotBlank(to.getUserOrderCode())) {
                    orderFormData.put("user_order_code", to.getUserOrderCode());
                }
                orderFormData.put("store_id", "1");

                // 添加订单项
                for (int i = 0; i < cartIdList.size(); i++) {
                    Integer orderId = cartIdList.get(i);
                    JsonNode matchedNode = successResultNode.get(i);
                    String matchedSku = matchedNode.path("sku").asText();

                    // 找到匹配的SKU
                    SKU matchingSku = skuList.stream()
                            .filter(sku -> sku.getSku().equals(matchedSku))
                            .findFirst()
                            .orElse(null);

                    if (matchingSku != null) {
                        orderFormData.put("items[" + i + "][id]", String.valueOf(orderId));
                        if (StringUtils.isNotBlank(matchingSku.getMaterialCode())) {
                            orderFormData.put("items[" + i + "][user_goods_code]", matchingSku.getMaterialCode());
                        }
                        if (StringUtils.isNotBlank(matchingSku.getDateCode())) {
                            orderFormData.put("items[" + i + "][date_code]", matchingSku.getDateCode());
                        }
                    }
                }

                // 发送下单请求
                String orderResponse = sendFormRequest(requestUrl + "/api-v1/order/add", orderFormData);
                log.info("云汉下单返回: {}", orderResponse);

                rootNode = objectMapper.readTree(orderResponse);
                String message = rootNode.path("message").asText();

                if (StringUtils.isNotBlank(message)) {
                    return CommonResult.error(500, message);
                }

                JsonNode resultNode = rootNode.path("result");
                String orderCode = resultNode.path("order_code").asText();

                return CommonResult.success(orderCode);
            }
        } catch (Exception e) {
            log.error("下单过程发生异常", e);
            return CommonResult.error(500, "下单失败: " + e.getMessage());
        }

        return CommonResult.error(500, "未知错误");
    }
}
